import md5 from './m'
import $CONSTENTS from './api'
import  NotificationCenter  from './NotificationCenter'
import RSA from './wx_rsa'

const rsaStr=str=>{//rsa加密
  let publicKey=wx.getStorageSync('publicKey')||'';
  publicKey=`-----BEGIN PUBLIC KEY-----${publicKey}-----END PUBLIC KEY-----`;
  let encrypt_rsa = new RSA.RSAKey();
  encrypt_rsa = RSA.KEYUTIL.getKey(publicKey);
  let encStr = encrypt_rsa.encrypt(str);
  encStr = RSA.hex2b64(encStr);
  return encStr
}
const randomString = a => {//32位字符串
    a = a || 32;
    const $chars = 'qwertyuiopasdfghjklzxcvbnm0123456789';
    const b = $chars.length;
    let c = '';
    for (let i = 0; i < a; i++) {
      c += $chars.charAt(Math.floor(Math.random() * b));
    }
    return c;
  }
const objKeySort = (obj) => {//排序的函数
    let newArr = Object.keys(obj).sort();//先用Object内置类的keys方法获取要排序对象的属性名，再利用Array原型上的sort方法对获取的属性名进行排序
    let newObj = {};
    for (let i = 0; i < newArr.length;i++)
    {
        newObj[newArr[i]] = obj[newArr[i]];
    }
    return newObj;
}
const getString = (a) => {//a是对象
    let b = '';
    for(let key of Object.keys(a))
    {
        b+=a[key];
    }
    return b;
}

  //获取token
 const getToken=()=>{
        let data={'grant_type': 'password','scope': 'read','username':'test','password':'test'};
        wx.request({
          header: { 'content-type': 'application/x-www-form-urlencoded' ,'Authorization':'Basic ZnJvbnRfYXBwOmZyb250X2FwcA=='},
          url: $CONSTENTS.TOKEN,
          data: data,
          method: 'POST',
          success: function(res){
            let data=res.data;
          if(data.flag){
            let { access_token, expires_in,refresh_token } = data.data;
            expires_in = Date.now() + expires_in * 1000-2000;
            wx.setStorageSync('access_token', access_token);
            wx.setStorageSync('expires_in', expires_in);
            wx.setStorageSync('refresh_token', refresh_token);
            wx.setStorageSync('keySerialNo', data.data.keyInfo.keySerialNo);
            wx.setStorageSync('publicKey', data.data.keyInfo.publicKey);
          }
          }
        })
  }

let center = new NotificationCenter();
center.registerNotification('token');//注册通知
//判断是否存在token
function fetchToken(fn) {//fn
  let token=wx.getStorageSync('access_token');
  let tokenExpireTime=Number(wx.getStorageSync('expires_in'));
  const currentTime = Date.now();
  //这里根据实际情况去判断是否有必要去请求或者刷新token。我这里用过期时间和缓存是否存在做一个样例
    if (token && currentTime <= tokenExpireTime) {//成功函数
         fn(token);//z执行下一步操作
  } else {//token已经过期
          if (center.isRequesting) {//正在更新token,将fn(item)其他队列添加到数组中
              center.addNotification('token', function(item){
                if (item.length > 0) {
                  fn(item)
                } 
              });
          } else {//token已经过期，第一个更新token的请求
            center.isRequesting = true;
            refreshToken().then(token=>{
              //在这里将获取的token以及其他相关信息缓存
              fn(token)
              center.distributeNotification('token',token);
              center.isRequesting = false;
            })
          }
   }
}
//刷新token
function refreshToken() {
  return new Promise(function(resolve, reject){
    let refresh_token=wx.getStorageSync('refresh_token') ;
    let data={'grant_type': 'refresh_token','refresh_token': refresh_token};
    wx.request({
      header: { 'content-type': 'application/x-www-form-urlencoded','Authorization':'Basic ZnJvbnRfYXBwOmZyb250X2FwcA==' },
      method: 'POST',
      url: $CONSTENTS.TOKEN,
      data:data,
      success: function(res){
        console.log(res.data)
        if(res.data.flag){
          let data=res.data.data;
          let { access_token, expires_in,refresh_token } = data;           
          expires_in = Date.now() + expires_in * 1000
          wx.setStorageSync('access_token', access_token);
          wx.setStorageSync('expires_in', expires_in);
          wx.setStorageSync('refresh_token', refresh_token);
          resolve(access_token)
        }else{//刷新失败，去登录
          wx.redirectTo({url:'../login/login?id=1'})
        }  
     }
    })
  })
}
const getData=(methods, param={},newType=true)=>{//请求数据
  return new Promise(function(resolve){
    fetchToken((token)=>{
      //在这里再执行接下来的数据请求即可
        const keySerialNo=wx.getStorageSync('keySerialNo');//序列号
        const ttp = new Date().getTime();
        const sk = randomString(32);
        let objectB = {
          tms: ttp,
          nonce: sk,
          method:methods,
          req_method:'MD5'
        }
     
        param=Object.assign(param,{keySerialNo});
        objectB = Object.assign(objectB, param);//于将所有可枚举属性的值从一个或多个源对象复制到目标对象(对象合并)（相同属性，后面覆盖前面）
        objectB = objKeySort(objectB);//对象属性排序
        let str=md5.hexMD5(encodeURIComponent(getString(objectB)));
        let objectC = { 'tms': ttp, 'nonce': sk, 'sign': str,method:methods,req_method:'MD5' };
        objectC = Object.assign(objectC, param)
        let Url=newType?$CONSTENTS.INDEX+methods:$CONSTENTS.INFO+methods;
        let header={'content-type': 'application/x-www-form-urlencoded','Authorization':`Bearer ${token}`,'req_terminal':'MINI','vn':'1.1','svn':'1.0.0','lau':'zh_CN','nw':'4G'};
        if(!newType){
           header['transferString']='lingjuntransferString';
        }
        let data=objectC
            wx.request({
              header: header,
              method: 'POST',
              url: Url,
              data:data,
              success: function(res){
                resolve(res)
              }
            })
      }) 
  })
}
  // const uploadFile = (fn,methods,tempFPaths,name,formData)=>{//图片上传
  //   const token=wx.getStorageSync('access_token');mpvue.getStorageSync('access_token');
  //   mpvue.uploadFile({
  //     url:$CONSTENTS.INDEX+methods, //仅为示例，非真实的接口地址
  //     filePath: tempFPaths,
  //     header: {'content-type': 'multipart/form-data','Authorization':`Bearer ${token}`},
  //     name: name,
  //     formData: formData,
  //     success :fn
  //   })
  // }
  module.exports = {
    getToken: getToken,
    getData:getData,
    rsaStr:rsaStr
  }